#include "common.h"


using namespace Scenic::Renderer;


extern ResourcePool imagePool;

ResourcePool contextPool;


Context::Context(Canvas *canvas)
: Resource(&contextPool)
{
	this->canvas = canvas;
	image = NULL;
	device = canvas->device;
	init();
}

Context::Context(Image *image)
: Resource(&contextPool)
{
	canvas = NULL;
	this->image = image;
	device = Device::getDefaultDevice();
	init();
}

Context::~Context()
{
	freeDeviceResources();
}

void Context::init()
{
	lineEdgeTexture = 0;
	lineDashTexture = 0;
	aaPolygonTexture = 0;
	polygonAntialias = false;
	filterKernel = NULL;
	primitives = 0;
	oldTexture = 0;
}

void Context::freeDeviceResources()
{
	if(oldTexture)
	{
		oldTexture->release();
		oldTexture = 0;
	}
	if(lineEdgeTexture)
		lineEdgeTexture->release();;
	if(lineDashTexture)
		lineDashTexture->release();
	if(aaPolygonTexture)
		aaPolygonTexture->release();
}

void Context::setPrimitives(Primitives *p)
{
	if(primitives)
	{
		primitives->draw();
	}
	primitives = p;
}

Context *Scenic::Renderer::getContext(int id)
{
	return (Context*)contextPool.get(id);
}

void Context::setRenderTarget(Surface *target)
{
	SurfaceInfo info = target->getInfo();

	device->setRenderTarget(target);
	initializeViewport(info.width, info.height);
}

void Context::initializeViewport(int width, int height)
{
	device->initializeViewport(width, height);
}

bool Context::beginScene()
{
	originalRenderTarget = device->getRenderTarget();

	if(!device->beginScene())
	{
		return false;
	}

	if(canvas)
	{
		Surface *surface = device->getRenderTarget();
		SurfaceInfo info = surface->getInfo();
		
		initializeViewport(info.width, info.height);
		clip = new ClipArea();
		clip->parent = 0;
		clip->x = 0;
		clip->y = 0;
		clip->width = info.width;
		clip->height = info.height;
		clip->offsetX = 0;
		clip->offsetY = 0;
		clip->surface = surface;
		clip->texture = 0;
		clip->type = SURFACE_TYPE_COLOR;
		clip->linearColorSpace = false;
	}
	else
	{
		clip = new ClipArea();
		clip->parent = 0;
		clip->x = 0;
		clip->y = 0;
		clip->width = image->width;
		clip->height = image->height;
		clip->offsetX = 0;
		clip->offsetY = 0;
		clip->type = SURFACE_TYPE_COLOR;
		clip->texture = image->getBlock(0, 0)->texture;
		clip->texture->addRef();
		clip->surface = clip->texture->getSurface(0);
		clip->linearColorSpace = false;
		
		setPrimitives(0);
		setRenderTarget(clip->surface);
	}

	width = clip->width;
	height = clip->height;

	return true;
}

void Context::endScene()
{
	setPrimitives(0);
	device->endScene();
	clip->surface->release();
	if(clip->texture)
		clip->texture->release();
	if(originalRenderTarget)
	{
		setRenderTarget(originalRenderTarget);
		originalRenderTarget->release();
	}
}
